package org.winexpress

import grails.converters.deep.JSON
import org.codehaus.groovy.grails.web.json.JSONObject;
import org.codehaus.groovy.grails.web.json.JSONArray;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;


class ContentManagementController {
    
    // reusable components
    def getCountryList() {
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/country").text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No countries.<br/><br/>'
                    try {
                        redirect(uri:"/404")
                    }
                    catch (CannotRedirectException) {
                        println 'already redirected...'
                    }
                }
            }
        }
        else {
            JSONArray arr = new JSONArray(txt)
            ArrayList<Country> countryList = new ArrayList<Country>()

            arr.each()
            {
                Country c = new Country()
                c.id = it.id
                c.countryName = it.countryName
                countryList.add(c)
            }

            return countryList
        }
    }
    
    def getSingleCountry(id) {
       
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/country/" + id).text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No countries.<br/><br/>'
                    try {
                        redirect(uri:"/404")
                    }
                    catch (CannotRedirectException) {
                        println 'already redirected...'
                    }
                }
            }
            else {
                Country c = new Country()
                c.id = o.get("id")
                c.countryName = o.get("countryName")
                
                return c
            }
        }
        else {
            flash.message = 'No specified country found.<br/><br/>'
            redirect(uri:"/")
        }
    }
    
    
    def getWineTypeList() {
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/wineType/").text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No wine types.<br/><br/>'
                    try {
                        redirect(uri:"/404")
                    }
                    catch (CannotRedirectException) {
                        println 'already redirected...'
                    }
                }
            }
        }
        else {
            JSONArray arr = new JSONArray(txt)
            ArrayList<WineType> wineTypeList = new ArrayList<WineType>()

            arr.each()
            {
                WineType wt = new WineType()
                wt.id = it.id
                wt.wineTypeName = it.wineTypeName
                wt.description = it.description
                wineTypeList.add(wt)
            }

            return wineTypeList
        }
    }
    
    def getSingleWineType(id) {
        String input = id
        String noSpaces = input.replaceAll(" ", "%20")
       
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/wineType/" + noSpaces).text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No wine types.<br/><br/>'
                    try {
                        redirect(uri:"/404")
                    }
                    catch (CannotRedirectException) {
                        println 'already redirected...'
                    }
                }
            }
            else {
                WineType wt = new WineType()
                wt.id = o.get("id")
                wt.wineTypeName = o.get("wineTypeName")
                wt.description = o.get("description")
                
                return wt
            }
        }
        else {
            flash.message = 'No specified wine type found.<br/><br/>'
            redirect(uri:"/")
        }
    }
    
    def getWineVarietalList() {
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/wineVarietal").text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No wine varietals.<br/><br/>'
                    try {
                        redirect(uri:"/404")
                    }
                    catch (CannotRedirectException) {
                        println 'already redirected...'
                    }
                }
            }
        }
        else {
            JSONArray arr = new JSONArray(txt)
            ArrayList<WineVarietal> wineVarietalList = new ArrayList<WineVarietal>()

            arr.each()
            {
                WineVarietal wv = new WineVarietal()
                wv.id = it.id
                wv.wineVarietalName = it.wineVarietalName
                wv.description = it.description
                
                WineType wt = it.wineType
                wv.wineTypeName = wt.wineTypeName
                wineVarietalList.add(wv)
            }

            return wineVarietalList
        }
    }
    
    def getSingleWineVarietal(id) {
       
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/wineVarietal/" + id).text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No wine varietals.<br/><br/>'
                    try {
                        redirect(uri:"/404")
                    }
                    catch (CannotRedirectException) {
                        println 'already redirected...'
                    }
                }
            }
            else {
                WineVarietal wv = new WineVarietal()
                wv.id = o.get("id")
                wv.wineVarietalName = o.get("wineVarietalName")
                wv.description = o.get("description")
                
//                WineType wt = getSingleWineType(o.get("wineType"))
//                wt.wineTypeName = wt.wineTypeName
                WineType wt = o.get("wineType")
                wv.wineTypeName = wt.wineTypeName
                
                return wv
            }
        }
        else {
            flash.message = 'No specified wine varietal found.<br/><br/>'
            redirect(uri:"/")
        }
    }
    
    def getWineRegionList() {
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/wineRegion/").text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No wine regions.<br/><br/>'
                    try {
                        redirect(uri:"/404")
                    }
                    catch (CannotRedirectException) {
                        println 'already redirected...'
                    }
                }
            }
        }
        else {
            JSONArray arr = new JSONArray(txt)
            ArrayList<WineRegion> wineRegionList = new ArrayList<WineRegion>()

            arr.each()
            {
                WineRegion wr = new WineRegion()
                wr.id = it.id
                wr.wineRegionName = it.wineRegionName
                wr.description = it.description
                
                Country c = getSingleCountry(it.countryId)
                wr.countryName = c.countryName
                wineRegionList.add(wr)
            }

            return wineRegionList
        }
    }
    
    def getSingleWineRegion(id) {
       
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/wineRegion/" + id).text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No wine regions.<br/><br/>'
                    try {
                        redirect(uri:"/404")
                    }
                    catch (CannotRedirectException) {
                        println 'already redirected...'
                    }
                }
            }
            else {
                WineRegion wr = new WineRegion()
                wr.id = o.get("id")
                wr.wineRegionName = o.get("wineRegionName")
                wr.description = o.get("description")
                
                Country c = getSingleCountry(o.get("countryId"))
                wr.countryName = c.countryName
                
                return wr
            }
        }
        else {
            flash.message = 'No specified wine region found.<br/><br/>'
            redirect(uri:"/")
        }
    }
    
    
    def getProductList(productType) {
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/product").text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No products.<br/><br/>'

                    redirect(uri:"/404")
                }
            }
        }
        else {
            JSONArray arr = new JSONArray(txt)
            ArrayList<Product> productList = new ArrayList<Product>()

            arr.each()
            {
                ProductType pt = it.productType
//                println pt.productTypeName
//                println productType
                if (pt.productTypeName.equalsIgnoreCase(productType)) {
                    Product p = new Product()
                    p.id = it.id
                    p.productName = it.productName
                    p.description = it.description
                    p.imageUrl = it.imageUrl
                    p.productTypeName = pt.productTypeName

                    productList.add(p)
                }
            }

            println productList.size()
            return productList
        }
    }
    
    def getSingleProduct(id) {
       
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/product/" + id).text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No specified product found.<br/><br/>'
                    redirect(uri:"/404")
                }
            }
            else {
                Product p = new Product()
                p.id = o.get("id")
                p.productName = o.get("productName")
                p.description = o.get("description")
                p.imageUrl = o.get("imageUrl")
                p.size = o.get("size")
                p.sellingPrice = o.get("sellingPrice")
                p.costPrice = o.get("costPrice")
                p.stockCount = o.get("stockCount")
                
                ProductType pt = o.get("productType")
                p.productTypeName = pt.productTypeName
                
                return p
            }
        }
        else {
            flash.message = 'No specified product found.<br/><br/>'
            redirect(uri:"/")
        }
    }
    
    def getProductOptionList(productId) {
        
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/product/" + productId + "/productOption").text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No productOptions.<br/><br/>'

                    redirect(uri:"/404")
                }
            }
        }
        else {
            JSONArray arr = new JSONArray(txt)
            ArrayList<ProductOption> productOptionList = new ArrayList<ProductOption>()

            arr.each()
            {
                ProductOption po = new ProductOption()
                po.id = it.id
                po.optionType = it.optionType
                po.optionTypeId = it.optionTypeId
                po.productId = it.productId
                
                productOptionList.add(po)
            }

            return productOptionList
        }
    }
    
    def getSingleProductOption(productId, id) {
       
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/productOption/" + id).text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No specified productOption found.<br/><br/>'
                    redirect(uri:"/404")
                }
            }
            else {
                ProductOption po = new ProductOption()
                po.id = o.get("id")
                po.optionType = o.get("optionType")
                po.optionTypeId = o.get("optionTypeId")
                po.productId = o.get("productId")
                
                return po
            }
        }
        else {
            flash.message = 'No specified product option found.<br/><br/>'
            redirect(uri:"/404")
        }
    }
    
//    def getInventoryList() {
//        
//        // consume winexpress server web service
//        def txt = new URL("http://localhost:8080/WineXpress/inventory/").text
//        
//        if (txt.getAt(0) == '{') {
//            JSONObject o = new JSONObject(txt)
//            if (o.has("404")) {
//                if (o.get("404") == true) {
//                    flash.message = 'No inventories.<br/><br/>'
//
//                    redirect(uri:"/404")
//                }
//            }
//        }
//        else {
//            JSONArray arr = new JSONArray(txt)
//            ArrayList<ProductOption> productOptionList = new ArrayList<ProductOption>()
//
//            arr.each()
//            {
////                Inventory i = new Inventory()
//                //todo: add invent
////                po.id = it.id
////                po.optionType = it.optionType
////                po.optionTypeId = it.optionTypeId
////                po.productId = it.productId
//                
//                productOptionList.add(po)
//            }
//
//            return productOptionList
//        }
//    }
//    
//    def getSingleInventoryByProductID(productId) {
//       
//        // consume winexpress server web service
//        def txt = new URL("http://localhost:8080/WineXpress/inventory/" + productId).text
//        
//        if (txt.getAt(0) == '{') {
//            JSONObject o = new JSONObject(txt)
//            if (o.has("404")) {
//                if (o.get("404") == true) {
//                    flash.message = 'No specified inventory found.<br/><br/>'
//                    redirect(uri:"/404")
//                }
//            }
//            else {
////                Inventory i = new Inventory()
//                //todo: add invent
////                po.id = o.get("id")
////                po.optionType = o.get("optionType")
////                po.optionTypeId = o.get("optionTypeId")
////                po.productId = o.get("productId")
//                
//                return i
//            }
//        }
//        else {
//            flash.message = 'No specified inventory found.<br/><br/>'
//            redirect(uri:"/404")
//        }
//    }
    
    def getRatingCommentList() {
        
        // consume winexpress server web service
        def txt = new URL("http://localhost:8080/WineXpress/ratingComment").text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    return 'No comments.<br/><br/>'
//                    redirect(uri:"/404")
                }
            }
        }
        else {
            JSONArray arr = new JSONArray(txt)
            ArrayList<RatingComment> ratingCommentList = new ArrayList<RatingComment>()

            IntRange indexRangeYear = new IntRange(0,3)
            IntRange indexRangeMonth = new IntRange(5,6)
            IntRange indexRangeDay = new IntRange(8,9)
            
            arr.each()
            {
                RatingComment rc = new RatingComment()
                rc.id = it.id
                def cdYear = it.creationDate.getAt(indexRangeYear)
                def cdMonth = it.creationDate.getAt(indexRangeMonth)
                def cdDay = it.creationDate.getAt(indexRangeDay)
                Date convertedCD = new Date()
                convertedCD.setDate(cdDay.toInteger())
                convertedCD.setMonth(cdMonth.toInteger()-1)
                convertedCD.setYear(cdYear.toInteger())
                convertedCD.setHours(0)
                convertedCD.setMinutes(0)
                convertedCD.setSeconds(0)
                rc.creationDate = convertedCD
                rc.comment = it.comment
                rc.rating = it.rating
                rc.customerId = it.customerId
                rc.productId = it.productId
                
                ratingCommentList.add(rc)
            }

            return ratingCommentList
        }
    }
    
    

    // initialization: GSP support operations (must be same as GSP filename)
    /* Product */
//    def productCreate = { 
//        println 'wine product create '
//    }
    
    def retrieveWineProducts = { 
        println 'wine product Retrieve '

        [products:getProductList("Wine")]
    }
    
    def retrieveGiftProducts = { 
        println 'gift product Retrieve '
        
        [products:getProductList("Gift")]
    }
    
    def retrieveHamperProducts = { 
        println 'hamper product Retrieve '
        
        [products:getProductList("Hamper")]
    }
    
    def retrieveProductDetail = {
        println 'retrieveProductDetail '
        
        def id = params["id"]
        
        Product p = getSingleProduct(id)
        ArrayList<ProductOption> poList = getProductOptionList(id)
        println "polist size : " + poList.size()
//        println poList
        
        def productTypeName = p.productTypeName
        def wineTypeName = "-"
        def wineVarietalName = "-"
        def wineRegionName = "-"
        
        poList.each() {
            if (it.productId == p.id) {
                if (it.optionType.equals("wineType")) {
                    WineType wt = getSingleWineType(it.optionTypeId)
                    wineTypeName = wt.wineTypeName
                    println 'has wineType'
                }
                
                if (it.optionType.equals("wineVarietal")) {
                    WineVarietal wv = getSingleWineVarietal(it.optionTypeId)
                    wineVarietalName = wv.wineVarietalName
                    println 'has wineVarietal'
                }
                
                if (it.optionType.equals("wineRegion")) {
                    WineRegion wr = getSingleWineRegion(it.optionTypeId)
                    wineRegionName = wr.wineRegionName
                    println 'has wineRegion'
                }
            }
        }
        
        int ratingCommentListSize = 0
        int ratingCount = 0
        int totalRating = 0
        double averageRating = 0
//        println "class: " + getRatingCommentList().class
        if (!getRatingCommentList().class.toString().equals("class java.lang.String")) {
            def rcList = getRatingCommentList()
            ratingCommentListSize = rcList.size()
            rcList.each() {
                if (it.rating != "") {
                    ratingCount++
                    totalRating += it.rating.toInteger()
                }
            }
            averageRating = totalRating/ratingCount
        }
        
        println p.id + " " + p.sellingPrice + " " + p.costPrice
        [product:p, productType:productTypeName, wineTypeName:wineTypeName, wineVarietalName:wineVarietalName, wineRegionName:wineRegionName, ratingComments:getRatingCommentList(), ratingCommentListSize:ratingCommentListSize, averageRating:averageRating, ratingCount:ratingCount]
    }
    
//    def productUpdate = { 
//        println 'wine product update '
//        
//        def id = params['id']
//        def typeName = params['typeName']
//        def description = params['description']
//        
//        [productId:id, productName:typeName, productDescription:description]
//    }
//    
//    def productDelete = { 
//        println 'wine product delete '
//    }
    
    def searchProducts ={}
    
    def searchProductsSubmit = {
        def queryString = ""
        
        def productName
        if (params['searchKey']) { productName = params['searchKey']; queryString += "productName=" + productName }
        def productType
        if (params['productType']) { productType = params['productType']; queryString += "productType=" + productType }
        def wineType = params['wineType']
        if (params['wineType']) { wineType = params['wineType']; queryString += "wineType=" + wineType }
        def wineVarietal = params['wineVarietal']
        if (params['wineVarietal']) { wineVarietal = params['wineVarietal']; queryString += "wineVarietal=" + wineVarietal }
        def wineRegion = params['wineRegion']
        if (params['wineRegion']) { wineRegion = params['wineRegion']; wineRegion += "wineRegion=" + wineRegion }
        
        println "queryString " + queryString
        
        // consume winexpress server web servic
        def txt = new URL("http://localhost:8080/WineXpress/product/search?" + queryString).text
        
        if (txt.getAt(0) == '{') {
            JSONObject o = new JSONObject(txt)
            if (o.has("404")) {
                if (o.get("404") == true) {
                    flash.message = 'No products found.<br/><br/>'

                    redirect(uri:"/")
                }
            }
        }
        else {
            JSONArray arr = new JSONArray(txt)
            ArrayList<Product> productList = new ArrayList<Product>()

            arr.each()
            {
                ProductType pt = it.productType
//                println pt.productTypeName
//                println productType
                
                Product p = new Product()
                p.id = it.id
                p.productName = it.productName
                p.description = it.description
                p.imageUrl = it.imageUrl
                println it.productType.productTypeName

                p.productTypeName = pt.productTypeName

                productList.add(p)
            }

            println productList.size()
           // return productList
           [productList:productList]
        }
    }
    
    
    
    /* RATING COMMENT */
    def productRatingComment = {
        def customerId = params['customerId']
        println customerId
        def productId = params['productId']
        println productId
        def productRating = params['productRating']
        println productRating
        def productComment = params['productComment']
        println productComment
        
        // create a JSONObject to send to winexpress server
        JSONObject o = new JSONObject()
        o.put("customer",customerId)
        o.put("product",productId)
        o.put("rating",productRating)
        o.put("comment",productComment)
        
        // to create use POST
        HttpClient httpclient = new DefaultHttpClient()
        HttpResponse response
        // consume winexpress server web service
        HttpPost httppost = new HttpPost("http://localhost:8080/WineXpress/ratingComment") // WineXpress Server's URI
        StringEntity se = new StringEntity(o.toString())          
        httppost.setEntity(se);          
        response = httpclient.execute(httppost);
        
        // get response code
        StatusLine status = response.getStatusLine()
        int statusCode = status.getStatusCode()
        
        println statusCode
        if (statusCode == 201) {
            flash.message = "Ratings and comments successfully created."
        }
        if (statusCode == 302) {
            flash.message = "Ratings and comments already exists."
        }
        if (statusCode == 400) {
            flash.message = "Ratings and comments could not be created. Please try again."
        }
        if (statusCode == 406) {
            flash.message = "Ratings and comments already exists."
        }

        redirect(uri:"/retrieveProductDetail")
    }
    
//    def productRating = {
//        
//    }
//    
//    def addCart =
//    {
//        def custId = 1//session.customerId
//        def productId = params['id']
//         JSONObject o = new JSONObject()
//        o.put("customer",custId)
//        o.put("product",productId)
//        HttpClient httpclient = new DefaultHttpClient()
//        HttpResponse response
//        // consume winexpress server web service
//        HttpPost httppost = new HttpPost("http://localhost:8080/WineXpress/addCart") // WineXpress Server's URI
//        StringEntity se = new StringEntity(o.toString())          
//        httppost.setEntity(se);          
//        response = httpclient.execute(httppost);
//    }
}
